<template>
    <div class="InboundList-box">
       <!-- 成绩列表 -->

        <h3 class="mb16">素养成绩</h3>
        <!-- 搜索栏 -->
        <serchForm :Form="inventoryForm" :FormLabel="inventoryFormLabel" @onSearch="onSearch" />
        <!-- 增删改查 -->
        <div class="function-box" v-if="checkPermi(['system:inventory:edit'])">
                <el-button class="addBtn2" @click="add">设置转换规则</el-button>
                <el-button class="addBtn2" @click="zhengshuS">生成证书</el-button>
        <div class="flex" style="display: flex; align-items: center; padding-left: 20px">
        <el-upload
          :auto-upload="false"
          :on-change="uploadHandle"
          :show-file-list="false"
          accept=".xlsx,.xls"
          action
          style="margin-right: 30px"
        >
          <template #trigger>
            <el-button class="addBtn2">导入</el-button>
          </template>
        </el-upload>
        <span
          style="color: #1a48fe; display: inline-block; margin: 20px 0; cursor: pointer"
          @click="downLoad"
        >
          下载导入模板</span
        >
      </div>
                <!-- <el-button class="delBtn2">删除</el-button> -->
        </div>
        <!-- 活动信息列表页面 -->
    <forTableCom
      :color="color"
      :idActive="idActive"
      :bg="bg"
      :total="total"
      :page="pageNum"
      :limit="pageSize"
      @handleSelectionChange="handleSelectionChange"
      @handleChange="handleChange"
      @updatePage="updatePage"
      @updateLimit="updateLimit"
      :tableHeaderData="inventoryTableHeaderData"
      :tableData="inventoryTableData"
      :gradeSetShow='gradeSetShow'
      @uploadView="uploadView"
      @uploadEdit="uploadEdit"
      :pagination="inventoryTableData.length>0"
    >
    </forTableCom>
    <!-- 学分转换规则弹出框 -->
       <el-dialog
      v-model="dialogVisible"
      title="设置转换规则"
      width="60%"
    >
      <div class="conversion-rules">
        <div class="rule-section">
          <h3>学分转换</h3>
          <p style="color: red;">请输入积分比例，例：10，则按照每10积分为1学分转换</p>
          <div class="conversion-item">
            <el-input-number v-model="creditRatio" :min="0" />
            <span>转换为</span>
            <el-input-number v-model="creditResult" :min="0" />
            <span>学分</span>
          </div>
        </div>

        <div class="rule-section">
          <h3>绩点转换</h3>
          <p style="color: red;">请输入学分区间，例：60-64，则按照每60-64学分为1绩点转换</p>
          <div class="range-conversion">
            <div class="range-item" v-for="(item, index) in rangeRules" :key="index">
              <el-input-number v-model="item.minValue" :min="0" @change="validateRanges(index)"/>
              <span>—</span>
              <el-input-number v-model="item.maxValue" :min="0" @change="validateRanges(index)"/>
              <span>转换为</span>
              <el-input-number v-model="item.resultValue" :min="0" />
              <span>绩点</span>
              <div class="action-buttons">
                <el-button
                  circle
                  :icon="Plus"
                  size="small"
                  @click="addRow(index)"
                  v-if="index === rangeRules.length - 1"
                />
                <el-button
                  circle
                  :icon="Minus"
                  size="small"
                  @click="removeRow(index)"
                  v-if="rangeRules.length > 1"
                />
              </div>
              <div class="error-message" v-if="item.error">
                {{ item.error }}
              </div>
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="resetRules">重置</el-button>
          <el-button type="primary" @click="submitRules">提交</el-button>
        </span>
      </template>
    </el-dialog>
    </div>
</template>

<script setup>
import { ref, reactive, toRefs,computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import serchForm from '@/components/inventory/serchForm.vue'
import { checkPermi } from '@/utils/permission.js'
import forTableCom from '@/components/forTableCom/index.vue'
import { ElMessage,ElMessageBox } from 'element-plus'
import {listUser,addUser,jifenDetail,zhengShu,recordsDaoru} from '@/api/grade/gradeSet.js'
import {quickCodeChildrenApi} from '@/api/system/dict/type.js'
import { getToken } from "@/utils/auth";
import { Plus, Minus } from '@element-plus/icons-vue';
import * as XLSX from 'xlsx'


const router = useRouter();
const route = useRoute();
const data = reactive({});
const { proxy } = getCurrentInstance();

const dialogVisible = ref(false); //控制弹出框打开关闭

const form = ref({
     fileUrl:'',      //文件地址
     fileType:'',       //类型
     name:'',   //组织
     remark:'',         //备注
     categoryCode:'',  //新增时候选择的类型
     fileSize:'',      //文件大小
  })
/** 重置操作表单 */
function reset() {
  form.value = {
    fileUrl: undefined, 
    name: undefined,
    remark: undefined,
    fileType:undefined,
  };
  proxy.resetForm("userRef");
};
const rules = ref({
    name: [{ required: true, message: "请输入组织", trigger: "blur" }],
    fileUrl: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
    categoryCode: [{ required: true, message: "请选择学期", trigger: "change"}],
  })

// 表单
let inventoryForm = ref({
  productCode:'',//学期
  uploadDate: '', // 学生姓名
  name: '', // 组织
  id: '', // 学号
})
// 表单数据标题
let inventoryFormLabel = ref([
  {
    name: 'uploadDate',
    label: '学生姓名',
  },
  {
    name: 'id',
    label: '学号',
  },
  {
    name: 'name',
    label: '组织',
  },
  {
    name: 'productCode',
    label: '学期',
    type:'select',
    client: [],
  },
])
// 查找
const onSearch = (v) => {
  console.log(v,'查看入库页面时间参数')
  // 每次查询后回到页1
  pageNum.value = 1
}

// 显示操作栏
const gradeSetShow = ref(true)
let idActive = 'id'
// 表格
let color = ref('#333')
let bg = ref('#d9d9d93b')
// 总条目数   pageSize 加 1
let total = ref(50)
// 当前页数
let pageNum = ref(1)
// 条数
let pageSize = ref(50)
// 存储勾选框的对象
let multipleSelection = ref([])
// 选中的列
let idList = []
const handleSelectionChange = (v) => {
  idList = v.map(item => item.userId);
}
// 分页器大小  当前分页器
const handleChange = (v) => {
  let { page, limit } = v.page
  pageNum.value = page
  pageSize.value = limit
  // let params = inventoryForm.value
  // listUser(params)
}
// 当前页面位置发生变化
const updatePage = (v) => {
  console.log(v)
}
// 条目个数发生变化
const updateLimit = (v) => {
  console.log(v)
}
// 表格表头数据
let inventoryTableHeaderData = ref([
  {
    prop: 'userName',
    label: '学号',
  },
  {
    prop: 'nickName',
    label: '学生姓名',
  },
  {
    prop: 'age',
    label: '年龄',
  },
  {
    prop: 'sex',
    label: '性别',
    sexGrade:true, //因为后端不是返回的男和女，是0和1,所以需要这个变量控制修改
  },
  {
    prop: 'deptNameList',
    label: '所属组织',
  },
  {
    prop: 'term',
    label: '学期',
  },
  {
    prop: 'pointsCount',
    label: '积分',
  },
  {
    prop: 'credit',
    label: '学分',
  },
  {
    prop: 'gpa',
    label: '绩点',
  },
])
// 表格数据内容
let inventoryTableData = ref([])
const uploadDel = (val)=>{  //列表单个删除操作
      let {i , v} = val
      console.log(v.id);
      
      ElMessageBox.confirm(
    '确定要删除该资料吗?',
    '删除',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(async() => {
         delUser(v.id).then(res=>{
              if(res.code===200){
                   ElMessage({
                 message: '删除成功',
                 type: 'success',
               })
               listUserApiFn()
              }
         })
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '已取消',
      })
    })
}
const uploadView = (val)=>{ //查看按钮
    let {i , v} = val
    router.push({path:`/point/${v.userId}/${v.nickName}/${v.dateId}`})
}
const zhengshuS = ()=>{  //批量生成证书
  if(idList.length===0){
       ElMessage({
                 message: '请先选择要下载的证书',
                 type: 'error',
               })
      return false
  }
    zhengShu({userIds:idList }).then(res => {
        // 创建一个 Blob 对象
        const blob = new Blob([res], { type: 'application/zip' });
        
        // 创建一个下载链接
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        
        // 设置下载的文件名（根据实际情况调整）
        a.download = 'certificate.zip'; // 或者从响应头获取文件名
        
        // 触发点击事件
        document.body.appendChild(a);
        a.click();
        
        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(a);
    }).catch(error => {
        console.error('下载证书失败:', error);
    });
}
const uploadEdit = (val) => { // 单个生成证书按钮
    let { i, v } = val;
    zhengShu({ userIds:[v.userId] }).then(res => {
        console.log(res, '证书生成');
        // 创建一个 Blob 对象
        const blob = new Blob([res], { type: 'application/zip' });
        // 创建一个下载链接
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        // 设置下载的文件名（根据实际情况调整）
        a.download = `certificate_${v.userId}.zip`; // 或者从响应头获取文件名
        // 触发点击事件
        document.body.appendChild(a);
        a.click();
        
        // 清理
        window.URL.revokeObjectURL(url);
        document.body.removeChild(a);
    }).catch(error => {
        console.error('下载证书失败:', error);
    });
};

const editId = ref(-1)
const add = ()=>{ //打开新增弹出框
    dialogVisible.value = true
    jifenDetail().then(res=>{  //回显学分规则详情数据
        if(res.code===200){
             res.data.forEach(item=>{
                 if(item.ruleType===1){
                    creditRatio.value = item.minValue
                    creditResult.value = item.resultValue
                 }
                  if(item.ruleType===2){
                      item.error = null
                  }
             })
            rangeRules.value = res.data.filter(item => item.ruleType===2);  //过滤ruleType===2的对象 
        }
    })
}
/** 提交按钮 */
function submitForm() {
  proxy.$refs["userRef"].validate(valid => {
    if (valid) {
       
    }
  });
};
const cancel = ()=>{
    
}
// 查询资料列表数据
const listUserApiFn = async (data = '') => {
  let page = {
    pageNum: pageNum.value,
    pageSize: pageSize.value,
  }
  let params = Object.assign(data, page)
  let res = await listUser(params)
  let { code, rows } = res
  if (code == 200) {
    console.log(rows,'打印学生成绩列表数据');
    // total.value = res.total
    inventoryTableData.value = rows
  }
}
let options = ref([])
const quickCodeChildrenApiFn =()=>{  //通过快码获得学期
    quickCodeChildrenApi({parentCode:30000}).then(res=>{
        console.log(res,'查询子集快码');
        if(res.code===200){
           options.value = res.rows
        }
    })
}

//动态表单
const creditRatio = ref(0);
const creditResult = ref(0);
const rangeRules = ref([
  { minValue:0, maxValue:0, resultValue:0, error: null,ruleType: 2, },
]);
const hasErrors = computed(() => {
  return rangeRules.value.some(item => item.error);
});
const addRow = (index) => {   //新增一行动态表单
  const lastItem = rangeRules.value[rangeRules.value.length - 1];
  rangeRules.value.push({
    minValue: lastItem.maxValue || 0,
    maxValue: lastItem.maxValue || 0,
    resultValue: lastItem.resultValue || 0,
    ruleType: 2,
  });
  validateRanges()

  // rangeRules.value.push({  //这里可以设置新增每一行动态表单增加固定的值
  //   min: lastItem.max + 1 || 0,
  //   max: lastItem.max + 5 || 0,
  //   result: lastItem.result + 0.5 || 0
  // });
};

const removeRow = (index) => {  //删除一行动态表单
  if (rangeRules.value.length > 1) {
    rangeRules.value.splice(index, 1);
  }
};

const resetRules = () => {  //重置
  creditRatio.value = 0;
  creditResult.value = 0;
  rangeRules.value = [
    { minValue: 0, maxValue: 0, resultValue: 0, error: null,ruleType: 2, },
  ];
};

const submitRules = () => {  //提交
  if(hasErrors.value==true){
            ElMessage({
                 message: '请根据红色请示正确填写数据后再提交',
                 type: 'error',
               })
               return false
       }
    
  rangeRules.value.push(
    {
      minValue: creditRatio.value,
      resultValue:creditResult.value,
      ruleType: 1,
    }
  )
  addUser(rangeRules.value).then(res=>{
    if(res.code===200){
        ElMessage({
                 message: '添加成功',
                 type: 'success',
               })
            dialogVisible.value = false;
            listUserApiFn()
    }
  })
};
const validateRanges = (changedIndex) => {  //input输入框事件
  // Clear all errors first
  rangeRules.value.forEach(item => item.error = null);
  
  // Validate each range
  for (let i = 0; i < rangeRules.value.length; i++) {
    const current = rangeRules.value[i];
    
    // Check minValue <= maxValue
    if (current.minValue > current.maxValue) {
      current.error = "最小值不能大于最大值";
      continue;
    }
    
    // Check for overlaps with other ranges
    for (let j = 0; j < rangeRules.value.length; j++) {
      if (i === j) continue;
      
      const other = rangeRules.value[j];
      console.log(current.minValue,current.maxValue,other.minValue,other.maxValue,'打印4个值');
      
      // Check for duplicate ranges
      if (current.minValue === other.minValue && current.maxValue === other.maxValue) {
        current.error = "不能有相同的区间范围";
        other.error = "不能有相同的区间范围";
        continue;
      }
      
      // Check for overlapping ranges
      if (
        (current.minValue >= other.minValue && current.minValue <= other.maxValue) ||
        (current.maxValue >= other.minValue && current.maxValue <= other.maxValue) ||
        (current.minValue <= other.minValue && current.maxValue >= other.maxValue)
      ) {
        current.error = "区间范围不能重叠";
        other.error = "区间范围不能重叠";
        continue;
      }
    }
  }
};


// 把文件按照二进制进行读取
const readFile = (file) => {
  return new Promise((resolve) => {
    let reader = new FileReader()
    reader.readAsBinaryString(file)
    reader.onload = (ev) => {
      resolve(ev.target.result)
    }
  })
}
// 导入
const importData = () => {}
let title = ref([])
const transformSupplierData = async (tableData, ev) => {
  title.value = []
  let file = ev.raw
  let data = await readFile(file)
  let workbook = XLSX.read(data, { type: 'binary' })
  let worksheet = workbook.Sheets[workbook.SheetNames[0]]
  data = XLSX.utils.sheet_to_json(worksheet)

  return data.map((value) => {
    return {
      userName: value['学号'] || null,
      creditValue: value['积分'] || null,
      activityId: value['活动编号'] || null,
    }
  })
}
// 暂存表格数据
let dataExacl = ref([])
let tableData = ref([])
const uploadHandle = async (ev) => {
  tableData.value = []
  dataExacl.value = []
  dataExacl.value = await transformSupplierData(tableData.value, ev)
  const isValid = dataExacl.value.every((item, index) => {
    return (
      item.userName !== null &&
      item.activityId !== null &&
      item.creditValue !== null
    )
  })
  if (isValid) {
    dataExacl.value.forEach(item=>{
      console.log(item,'打印导入的item数据');
      item.userName = String(item.userName)
      item.activityId = String(item.activityId)
      let listItem = [item]
     recordsDaoru(listItem).then(res=>{
          if (res.code === 200) {
      ElMessage({
        message: '导入成功',
        type: 'success',
      })
    }
      })
    })
    listUserApiFn() //新增表格数据后刷新页面数据条数
  } else {
    ElMessage.error('请完善文件必填数据！')
  }
}
const downLoad = () => {   //下载excel模板
  let a = document.createElement('a')
  let evt = document.createEvent('MouseEvents')
  a.download = '学分导入'
  a.href = '/xuefen.xlsx'
  evt.initEvent('click', true, true)
  a.dispatchEvent(evt)
  window.URL.revokeObjectURL(a.href)
}
onMounted(()=>{
    Promise.all([listUserApiFn(),quickCodeChildrenApiFn()])
})

</script>

<style lang='scss' scoped>
.InboundList-box {
    padding: 16px;
    .function-box {
    display: flex;
    align-items: center;
  }
}

.conversion-rules {
  padding: 0 20px;
}

.rule-section {
  margin-bottom: 30px;
}

.rule-section h3 {
  margin-bottom: 10px;
  font-size: 16px;
  color: #333;
}

.rule-section p {
  margin-bottom: 15px;
  color: #666;
  font-size: 14px;
}

.conversion-item {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 15px;
}

.range-conversion {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.range-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: 4px;
  background-color: #fafafa;
}

.error-item {
  border: 1px solid #f56c6c;
  background-color: #fef0f0;
}

.error-message {
  color: #f56c6c;
  font-size: 12px;
  margin-left: 10px;
}


.action-buttons {
  display: flex;
  gap: 5px;
  margin-left: 10px;
}

.dialog-footer {
  display: flex;
  justify-content:center;
  gap: 10px;
}
</style>

